home *** CD-ROM | disk | FTP | other *** search
- /*
- * init.c - initialization routines
- */
- #include "RevRdist.h"
- #include <GestaltEqu.h>
- #include "TransSkelProto.h"
- #include "TransDisplayProto.h"
- #include "desktop.h"
- #include <Finder.h>
- #include <Errors.h>
- #include <AppleEvents.h>
-
- extern unsigned char ApplScratch[12] : 0xA78;
-
- /*
- * prototypes for functions in AppleEvents.c
- */
- OSErr DoHighLevelEvent (EventRecord *theEvent);
- OSErr init_AppleEvent(Boolean);
-
- void checkRun(void);
- void checkVersion(void);
- OSErr get_launch_args (void);
- void quitOthers(void);
-
-
-
- /*
- *=========================================================================
- * checkRun - check if we should run now
- * entry: File_list[FL_PREF], Prefs[P_WORK] set
- * exit: Quit = true if application must quit immediately
- *=========================================================================
- */
- void
- checkRun (void)
- {
- file_info_t *fi; /* ptr in File_list */
- unsigned long now, atime; /* for time calcs */
- prefs_t *pi;
-
- /*
- * If not running automatically, make no decision
- */
- if (!(Flags & PF_STARTUP))
- return;
- GetDateTime (&now);
- /*
- * Check if update interval being observed and it is not time yet
- */
- if (Flags & PF_TOUCH)
- {
- fi = &File_list[FL_PREF];
- pi = &Prefs[P_WORK];
- if (fi->f_set)
- {
- atime = fi->f_info.mdDate + pi->p_interval;
- if (now < atime)
- {
- Quit = 1;
- }
- }
- }
- }
-
-
-
- /*
- *=========================================================================
- * checkVersion - check if we are an old version and a newer version is
- * present
- * entry: File_list[FL_APPL] filled in
- * exit: Quit = true if application must quit immediately
- *=========================================================================
- */
- void
- checkVersion (void)
- {
- OSErr error;
- file_info_t *fi; /* ptr in File_list */
- int idx; /* for scanning folder */
- unsigned long mdDate; /* our mod time */
- Longint parID; /* our parent folder */
- Integer vol; /* our vRefNum */
- CInfoPBRec ci;
- Str255 name;
-
- /*
- * Check for another copy of us in the same folder.
- * If present and newer, quit.
- */
- fi = &File_list[FL_APPL];
- vol = fi->f_vol;
- parID = fi->f_info.parID;
- mdDate = fi->f_info.mdDate;
- ZERO(ci);
- ci.hFileInfo.ioNamePtr = name;
- for (idx = 1; ; idx++)
- {
- name[0] = 0;
- ci.hFileInfo.ioVRefNum = vol;
- ci.hFileInfo.ioFDirIndex = idx;
- ci.hFileInfo.ioDirID = parID;
- error = PBGetCatInfo (&ci, false);
- if (error)
- break;
- if ((ci.hFileInfo.ioFlAttrib & ioDirMask) == 0
- && ci.hFileInfo.ioFlFndrInfo.fdCreator == CREATOR
- && ci.hFileInfo.ioFlFndrInfo.fdType == 'APPL'
- && ci.hFileInfo.ioFlMdDat > mdDate)
- {
- FlashMenuBar(0);
- Quit = 1;
- break;
- }
- }
- }
-
-
-
-
- /*
- *=========================================================================
- * initGlobals - set up the (too many) global variables
- * exit: Quit = false if initialization succeeded
- * Quit = true if application must quit immediately
- *=========================================================================
- */
- void
- initGlobals ()
- {
- OSErr error;
- file_info_t * fi; /* ptr into File_list[] */
- Handle h; /* temp handle */
- long * lp; /* ptr into ApplScratch */
- StringHandle sh; /* temp string handle */
- SysEnvRec theWorld; /* environment info */
- WindowPtr w; /* working window pointer */
- WDPBRec wdpb; /* to get boot volume */
- Str255 pname; /* prefs file name */
-
- HighValue[0] = 3;
- HighValue[1] = HighValue[2] = HighValue[3] = 255;
- Clue0 = "\pinitGlobals";
- Quit = false;
- Ap_refNum = CurResFile ();
- error = SysEnvirons (1, &theWorld);
- if (error)
- {
- Quit = true;
- return;
- }
- BlessedWD = theWorld.sysVRefNum;
- ZERO (wdpb);
- wdpb.ioVRefNum = BlessedWD;
- error = PBGetWDInfo (&wdpb, false);
- if (error)
- {
- Quit = true;
- return;
- }
- /*
- * Make sure we are running under HFS
- */
- if (FSFCBLen < 0)
- {
- panic (true, E_HFS, CurApName, nil);
- return;
- }
- BootVol = wdpb.ioWDVRefNum;
- /*
- * Allocate File_list and insert info about Application
- */
- File_list = (file_info_t *) NewPtr (FL_MAX * sizeof (* File_list));
- if (!File_list)
- goto nomem;
- memset ((char *)File_list, 0, FL_MAX * sizeof (* File_list));
-
- fi = &File_list[FL_APPL];
- fi->f_ref = Ap_refNum;
- fi->f_info.ctype = C_FILE;
- if (error = getInfoByPath ("\p", fi))
- goto sysdie;
- fi->f_launch = true;
-
- /*
- * Set processing flag bits
- * Check ApplScratch for our signature to see if
- * we are running automatically at boot time.
- * That works if we were started by RevRINIT.
- * We might also start because we are in the Startup Items folder.
- * Check for that also.
- */
- Flags = 0;
- h = Get1Resource (TYPE_LONG, FLAG_PARM);
- if (h)
- {
- Flags = **((long **)h);
- ReleaseResource (h);
- }
- lp = (long *)(ApplScratch + 8);
- if (lp[0] == CREATOR)
- {
- Flags |= PF_STARTUP;
- lp[0] = 0;
- }
- if (!(Flags & PF_STARTUP))
- {
- Longint lt;
- Integer itemp;
-
- error = TickCount() > 3 * 60 * 60; /* within 3 min of start up ? */
- if (!error)
- error = Gestalt(gestaltFindFolderAttr, <);
- if (!error)
- error = !(lt & (1<<gestaltFindFolderPresent));
- if (!error)
- error = FindFolder (BootVol, 'strt', kDontCreateFolder, &itemp, <);
- if (!error && (lt == fi->f_info.parID))
- Flags |= PF_STARTUP;
- error = 0;
- }
- /*
- * Test if we are old version
- */
- if (Flags & PF_STARTUP)
- checkVersion();
- if (Quit)
- {
- Flags &= ~PF_RESTART;
- return; /* yes, exit now without reboot */
- }
- /*
- * Continue filling in File_list with
- * info about any files passed as parameters
- */
- error = get_launch_args();
- if (error)
- goto sysdie;
- /*
- * Bring up flags dialog if selected
- */
- if ((Flags & PF_DIALOG) || ((Flags & PF_LOCKED) == 0 && Button()))
- setFlags ();
- else if ((Flags & (PF_STARTUP|PF_FINDUPD)) == (PF_STARTUP|PF_FINDUPD))
- {
- int i;
- EventRecord theEvent;
- /*
- * We need a dummy event loop here to give AppleShare time to start up
- */
- for (i = 0; i < 4; i++)
- {
- if (WaitNextEvent(everyEvent, &theEvent, 60, nil))
- {
- switch (theEvent.what)
- {
- }
- }
- }
- }
- if (Quit)
- return;
- ActivityWind = GetNewDWindow (RSRC_BASE+WIND_ACTIVITY, (WindowPtr) -1L);
- ErrorWind = GetNewDWindow (RSRC_BASE+WIND_ERRORS, (WindowPtr) -1L);
- SetDWindow (ActivityWind);
- /*
- * Get junking renaming suffix
- */
- h = GetResource ('STR ', STR_JUNKSUF);
- if (!h || **h > sizeof (Junksuf) - 1 || **h < 2)
- {
- panic (true, E_BADJUNKF, nil);
- return;
- }
- COPYPS (*h, Junksuf);
- ReleaseResource (h);
- /*
- * Get name for anonymous documents
- */
- h = GetResource ('STR ', STR_UNTITLED);
- if (!h)
- {
- error = ResError ();
- goto sysdie;
- }
- Untitled = (StringHandle) h;
- /*
- * Get names for temp files
- */
- h = GetResource ('STR ', STR_TEMP1);
- if (!h || **h > sizeof (TempName) - 1 || **h < 2)
- {
- panic (true, E_BADTEMPF, nil);
- return;
- }
- COPYPS (*h, TempName);
- ReleaseResource (h);
- h = GetResource ('STR ', STR_TEMP2);
- if (!h || **h > sizeof (TempName2) - 1 || **h < 2)
- {
- panic (true, E_BADTEMPF, nil);
- return;
- }
- COPYPS (*h, TempName2);
- ReleaseResource (h);
- /*
- * Initialize preferences from application
- */
- memset ((char *)&Prefs[0], 0, 2 * sizeof (prefs_t));
- if (prefFetch (File_list[FL_APPL].f_ref) == 0)
- prefMerge (P_WORK, false);
- /*
- * Load preferences from file.
- * If we haven't located a preferences file yet, try finding the one
- * given by the preferences string within the application.
- * It's not a problem if we cannot find the file.
- */
- error = 0;
- fi = &File_list[FL_PREF];
- if (fi->f_set)
- {
- COPYPS(fi->f_info.name, pname); /* save name for msg */
- error = prefFFetch (fi);
- }
- else
- {
- sh = (StringHandle) GetResource ('STR ', STR_PREFS);
- if (!sh)
- {
- panic (true, E_SYS, Clue0,
- "\pGetResource", "\ppref file name");
- return;
- }
- COPYPS (*sh, pname);
- ReleaseResource ((Handle) sh);
- fi->f_vol = 0;
- fi->f_ref = 0;
- error = getInfoByPath (pname, fi);
- if (error == 0)
- error = prefFFetch (fi);
- }
- if (error == 0)
- prefMerge (P_WORK, true);
- Prefs[P_WORK].p_modified = false;
- if (error)
- {
- /*
- * Tell about no prefs
- * If not startup, see if we should continue.
- */
- panic (Flags & PF_STARTUP, E_PREFS, pname, nil);
- if (Quit && (Flags & PF_STARTUP))
- Flags &= ~PF_RESTART; /* avoid reboot loop */
- }
- if (Quit)
- return;
- checkRun(); /* see if time to run */
- if (Quit)
- {
- Flags &= ~PF_RESTART; /* not time, let sys come up */
- return;
- }
- /*
- * Kill off other processes if requested
- */
- if (Flags & PF_QUITOTHERS)
- quitOthers();
- return;
-
- sysdie:
- ClueID = error;
- panic (true, E_SYS, Clue0, nil);
- Quit = true;
- return;
-
- nomem:
- SysBeep (5);
- Quit = true;
- return;
- }
-
-
-
- /*
- *=========================================================================
- * get_launch_args () - find out why we were launched
- * That is, get any files used to start us
- * returns OSErr
- * File_list[] possibly modified
- *=========================================================================
- */
- OSErr
- get_launch_args(void)
- {
- OSErr error;
- Integer fcount, fmsg; /* Finder args */
- int i;
- file_info_t *fi; /* ptr into File_list */
- Longint lp;
- EventRecord theEvent;
-
- /*
- * Check if Apple Event are supported.
- * If not, get files the old, simple way.
- * Otherwise, use kludgy code to get the Apple events which give
- * us the file info
- */
- lp = 0;
- error = Gestalt (gestaltAppleEventsAttr, &lp);
- if (error || (lp & (1<<gestaltAppleEventsPresent)) == 0)
- {
- /*
- * Hurray! No Apple events to contend with
- */
- error = 0;
- CountAppFiles (&fmsg, &fcount);
- if (fmsg == 1 && fcount > 0)
- {
- panic (false, E_NOPRINT, nil);
- if (Quit)
- return;
- }
-
- Ap_file.fType = 0;
- for (i = 1; i <= fcount; i++)
- {
- int j;
-
- GetAppFiles (i, &Ap_file);
- switch (Ap_file.fType)
- {
- case TYPE_PREF: j = FL_PREF; break;
- case TYPE_CONT: j = FL_DIST; break;
- case 'INIT': j = -1; Flags |= PF_STARTUP; break;
- default: j = -1; break;
- }
- if (j >= 0)
- {
- fi = &File_list[j];
- fi->f_vol = Ap_file.vRefNum;
- error = getInfoByPath (Ap_file.fName, fi);
- if (error == 0)
- fi->f_launch = true;
- }
- ClrAppFiles (i);
- }
- return error;
- }
- /*
- * Ugh! Use a dummy event loop to give the system time to send
- * us the events which started us
- */
- error = init_AppleEvent(true);
- for (i = 0; i < 100; i++)
- {
- if (WaitNextEvent(everyEvent, &theEvent, 0, nil))
- {
- switch (theEvent.what)
- {
- case kHighLevelEvent:
- i = 100;
- error = DoHighLevelEvent(&theEvent);
- break;
- }
- }
- }
- (void) init_AppleEvent(false); /* remove handlers */
- return error;
- }
-
-
-
- /*
- *=========================================================================
- * quitOthers () - try to cause other applications to quit
- *=========================================================================
- */
- void
- quitOthers (void)
- {
- OSErr error;
- OSType theType; /* process file type */
- OSType theSig; /* process signature */
- Longint lp; /* for Gestalt */
- unsigned long ticks; /* the ticks */
- int gotone; /* true if signaled a process */
- ProcessSerialNumber process;
- ProcessInfoRec inforec;
- FSSpec fsspec;
- Str31 pname; /* process name */
- AEDesc target;
- AppleEvent theEvent;
- EventRecord event; /* for WaitNextEvent() */
-
- /*
- * Check for process manager.
- * Give up if not present
- */
- error = Gestalt(gestaltOSAttr, &lp);
- if (error)
- return;
- if (!(lp & (1<<gestaltLaunchControl)))
- return;
- for (ticks = TickCount() + 30*60, gotone = 1; gotone && TickCount() < ticks;)
- {
- gotone = 0;
- /*
- * Scan running processes
- */
- ZERO (process);
- ZERO (theEvent);
- ZERO (target);
- ZERO (inforec);
- process.lowLongOfPSN = kNoProcess;
-
- inforec.processInfoLength = sizeof(inforec);
- inforec.processName = pname;
- inforec.processAppSpec = &fsspec;
-
- do
- {
- error = GetNextProcess(&process);
- if (error == 0)
- error = GetProcessInformation (&process, &inforec);
- if (error == 0)
- {
- theSig = inforec.processSignature;
- theType = inforec.processType;
- /*
- * Try to quit Finder, applications, and desk accessories
- */
- if ( (theSig == 'MACS' && theType == 'FNDR')
- || (theType == 'APPL' && theSig != CREATOR)
- || (inforec.processMode & modeDeskAccessory)
- )
- {
- error = AECreateDesc (typeProcessSerialNumber,
- (Ptr)&process, sizeof (process),
- &target);
- if (error == 0)
- error = AECreateAppleEvent (kCoreEventClass, kAEQuitApplication,
- &target, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
- if (error == 0)
- error = AESend (&theEvent, nil, kAENoReply,
- kAENormalPriority, kNoTimeOut, nil, nil);
- if (error == 0)
- gotone = 1;
- error = 0;
- AEDisposeDesc(&theEvent);
- AEDisposeDesc(&target);
- }
- }
- } while (error == 0);
- if (gotone)
- (void) WaitNextEvent(everyEvent, &event, 20, nil);
- }
- }
-
-
- /*
- *=========================================================================
- * tidyUp () - do final cleanup before exiting
- *=========================================================================
- */
- void
- tidyUp ()
- {
- desktop_end();
- }
-